#pragma once
#include <iostream>
#include <vector>
#include <string>
#include "Inet.hpp"
#include "ThreadPool.hpp"

// 完成消息转发
class Route
{
private:
    using task_t = std::function<void()>;

public:
    // 转发服务的函数类型
    using service_t = std::function<void(int socket, const std::string &message, const Inet &)>;
    Route()
        : _online_user()
    {
    }

    // 检查在线用户列表
    void CheckOnlineUser(const Inet &who)
    {
        for (auto &user : _online_user)
        {
            if (user == who)
            {
                LOG(DEBUG,"%s exists\n",who.UniqueName().c_str());
                return;
            }
        }
        // 走到这里，说明who不在用户列表,添加到用户列表
        _online_user.push_back(who);
        LOG(DEBUG,"%s is not exist,add it\n",who.UniqueName().c_str());
    }

    // 转发逻辑
    void FowardHelper(int sockfd, const std::string &message)
    {
        for (auto &user : _online_user)
        {
            struct sockaddr_in peer = user.ADDR();
            sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&peer, sizeof(peer));
        }
    }

    void Foward(int sockfd, const std::string &message, const Inet &who)
    {
        // 检查用户是否在onlineuser中，如果不在，添加;如果在，不做任何事
        CheckOnlineUser(who);

        // 转发信息 —— 单线程
        // FowardHelper(sockfd,message);

        // 使用多线程转发，主线程检查在线用户逻辑，使用多线程来遍历在线用户列表转发信息

        Route::task_t t = std::bind(&Route::FowardHelper, this, sockfd, message); ///////////////////////////////////////////
        ThreadPool<task_t>::GetInstance()->PushTask(t);
    }

    ~Route()
    {
    }

private:
    std::vector<Inet> _online_user;
};
